﻿using System;
using System.Collections.Generic;
using System.Text;
using dotNET.Application.Infrastructure;
using dotNET.Repository;
using dotNET.Data;
using dotNET.Domain.Entities;
using System.Threading.Tasks;
using dotNET.Utility;
using dotNET.Dto;
using System.Linq;
using dotNET.Utility.Cache;
using dotNET.Domain.ViewModel;
using Microsoft.Extensions.Logging;
namespace dotNET.Application.App
{
    public class RoleAuthorizeApp : App, IRoleAuthorizeApp
    {
        public IRepositoryBase<RoleAuthorize> _roleAuthorizeRep { get; set; }
        public IModuleApp _moduleApp { get; set; }

        public IModuleButtonApp _moduleButtonApp { get; set; }

        public ICacheService _cache { get; set; }
  
        public async Task<R> CreateAsync(RoleAuthorize entity)
        {
            var r = await _roleAuthorizeRep.InsertAsync(entity);
            if (r > 0)
                return R.Suc();
            return R.Err();
        }

        public async Task CreateAsync(List<RoleAuthorize> entitys)
        {
            foreach (RoleAuthorize entity in entitys)
            {
                await _roleAuthorizeRep.InsertAsync(entity);
            }
        }
        public async Task DeleteAsync(long Id)
        {
            await _roleAuthorizeRep.DeleteAsync(Id);
        }
        public async Task DeleteAsync(IEnumerable<long> Ids)
        {
            if (Ids.Count() > 0)
                await _roleAuthorizeRep.DeleteListAsync("Where `Id` in @Ids", new { Ids = Ids });
        }
        public async Task<List<RoleAuthorize>> GetListAsync(long ObjectId, int ObjectType)
        {
            List<RoleAuthorize> data;
              data = await _cache.GetAsync<List<RoleAuthorize>>("GetClientsDataJson", ObjectId.ToString());
            if (data == null)
            {
                data = (await _roleAuthorizeRep.GetListAsync(new { ObjectId = ObjectId, ObjectType = ObjectType })).ToList();
                await _cache.AddAsync("GetClientsDataJson", data, new TimeSpan(0, 30, 0), ObjectId.ToString());
            }
            return data;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="roleId"></param>
        /// <param name="curUser"></param>
        /// <returns></returns>
        public async Task<List<Module>> GetModuleList(long roleId, bool bSys)
        {
            List<Module> data;
            if (bSys)
            {
                data = await _cache.GetAsync<List<Module>>("sys", "modules");
                if (data == null)
                {
                    data = await _moduleApp.GetSaasModuleListAsync(new ModuleOption { IsEnabled = true });
                    await _cache.AddAsync("sys", data, new TimeSpan(0, 30, 0), "modules");
                }  
            }
            else
            {
                data = await _cache.GetAsync<List<Module>>(roleId.ToString(), "modules");
                if (data == null)
                {
                    data = new List<Module>();
                    var moduledata = await _moduleApp.GetSaasModuleListAsync(new ModuleOption { IsEnabled = true });
                    var authorizedata = await _roleAuthorizeRep.GetListAsync(new { ObjectId = roleId, ItemType = 1 });
                    foreach (var item in authorizedata)
                    {
                        Module moduleEntity = moduledata.Find(t => t.Id == item.ItemId);
                        if (moduleEntity != null)
                        {
                            data.Add(moduleEntity);
                        }
                    }
                    await _cache.AddAsync(roleId.ToString(), data, new TimeSpan(0, 30, 0), "modules");
                }
            }
            return data.OrderBy(t => t.SortCode).ToList();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="roleId"></param>
        /// <param name="curUser"></param>
        /// <returns></returns>
        public async Task<List<ModuleButton>> GetButtonList(long roleId, bool bSys)
        {
            List<ModuleButton> data;
            if (bSys)
            {
                data = await _cache.GetAsync<List<ModuleButton>>("sys", "buttons");
                if (data == null)
                {
                    data = await _moduleButtonApp.GetSaasModuleListAsync(new ModuleButtonOption { IsEnabled = true });
                    await _cache.AddAsync("sys", data, new TimeSpan(0, 30, 0), "buttons");
                }
            }
            else
            {
                data = await _cache.GetAsync<List<ModuleButton>>(roleId.ToString(), "buttons");
                if (data == null)
                {
                    data = new List<ModuleButton>();
                    var buttondata = await _moduleButtonApp.GetSaasModuleListAsync(new ModuleButtonOption { IsEnabled = true });
                    var authorizedata = await _roleAuthorizeRep.GetListAsync(new { ObjectId = roleId, ItemType = 2 });
                    foreach (var item in authorizedata)
                    {
                        ModuleButton moduleButtonEntity = buttondata.Find(t => t.Id == item.ItemId);
                        if (moduleButtonEntity != null)
                        {
                            data.Add(moduleButtonEntity);
                        }
                    }
                    await _cache.AddAsync(roleId.ToString(), data, new TimeSpan(0, 30, 0), "buttons");
                }
            }
            return data.OrderBy(t => t.SortCode).ToList();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="roleId"></param>
        /// <param name="action"></param>
        /// <returns></returns>
        public async Task<bool> ActionValidate(long roleId, string action)
        {
            var authorizeurldata = new List<AuthorizeActionModel>();
            var cachedata =  await _cache.GetAsync<List<AuthorizeActionModel>>(roleId.ToString(), "authorizeurl");
            if (cachedata == null)
            {
                var moduledata = await _moduleApp.GetSaasModuleListAsync();
                var buttondata = (await _moduleButtonApp.GetSaasModuleListAsync());
                var authorizedata = await _roleAuthorizeRep.GetListAsync(new { ObjectId = roleId });
                foreach (var item in authorizedata)
                {
                    if (item.ItemType == 1)
                    {
                        Module module = moduledata.Find(t => t.Id == item.ItemId);
                        if(module!=null)
                        authorizeurldata.Add(new AuthorizeActionModel { Id = module.Id, UrlAddress = module.UrlAddress });
                    }
                    else if (item.ItemType == 2)
                    {
                        ModuleButton moduleButton = buttondata.Find(t => t.Id == item.ItemId);
                        if (moduleButton != null)
                            authorizeurldata.Add(new AuthorizeActionModel { Id = moduleButton.ModuleId, UrlAddress = moduleButton.UrlAddress });
                    }
                }
                await _cache.AddAsync(roleId.ToString(), authorizeurldata, new TimeSpan(0, 30, 0), "authorizeurl");
            }
            else
            {
                authorizeurldata = cachedata;
            }
            foreach (var item in authorizeurldata)
            {
                if (!string.IsNullOrEmpty(item.UrlAddress))
                {
                    string[] url = item.UrlAddress.Split('?');
                    if (url[0].ToLower() == action.ToLower())
                    {
                        return true;
                    }
                }
            }
            return false;
        }
    }
}
